#include <stdio.h>
#include "flv.h"
#include "flvio.h"

/**
 * tagbuf_fread() - read some bytes to tagbuf; increase allocation if used up
 * @return: -1: fread() failure; ENOMEM.
 */
static int tagbuf_fread(struct tagbuf *b, size_t len, FILE *in)
{
	if (!len)
		return 0;
	if (b->used + len > b->allocated) {
		b->allocated *= 2;
		b = tagbuf_realloc(b, b->allocated);
		if (!b)
			return -1;
	}
	if (!fread(b->data + b->read, len, 1, in))
		return -1;
	b->used += len;
	b->read += len;
	return 0;
}

/**
 * read_tag() - read a complete tag
 * @not_first: first hdr/tag needs to be differentiated.
 * @return: -1: fread() errors; ENOMEM.
 *
 * The tagbuf contains undefined content after failed calls, must be freed.
 */
int read_tag(FILE *in, struct tagbuf *b, int not_first)
{
	tagbuf_clear(b);

	if (tagbuf_fread(b, FLV_HDR_LEN, in) < 0)
		return -1;

	if (not_first)
		b->is_tag = 2;
	else
		b->is_tag = flv_is_tag(b);

	if (b->is_tag) {
		b->hdrlen = FLV_TAGHDR_LEN;
		if (tagbuf_fread(b, FLV_TAGHDR_LEN - FLV_HDR_LEN, in) < 0)
			return -1;
		b->len = flv_size(b);
	} else {
		b->hdrlen = FLV_HDR_LEN;
		b->len = flv_off(b) - FLV_HDR_LEN;
	}

	if (tagbuf_fread(b, b->len + 4, in) < 0)
		return -1;

	return 0;
}

/**
 * write_tag() - write a complete tag
 * @return: -1 on fwrite() failure.
 */
int write_tag(FILE *out, const struct tagbuf *b)
{
	if (b->is_linear) {
		if (!fwrite(b->data, b->used, 1, out))
			return -1;
	} else {
		if (!fwrite(tagbuf_hdr(b), b->hdrlen, 1, out))
			return -1;
		if (b->len)
			if (!fwrite(tagbuf_payload(b), b->len, 1, out))
				return -1;
		if (!fwrite(tagbuf_pts(b), 4, 1, out))
			return -1;
	}
	return 0;
}
